/*
	This file defines the core class consisting of different layers such as regions and curves.
	These layers are combined in occlusive fashion, called occlusive model instead of
	addative model which can be seen in the matching pursuit algorithm.
	Rather than coordinating all the layers, this class only play the role of
	storing and passing messages layers. The class mcmcSymphony controls different
	layers through Markov Chain dynamics to give birth, kill, and change the elements
	in each layer.
*/
#ifndef _MCMC_MAP_H
#define _MCMC_MAP_H

#include "mcmcLayerRegion.h"

////////////////////////////////////////////////
// class for exchanging data
class MCMC_SegSetting
{
public:
	// constructor and destructor
	MCMC_SegSetting();
	~MCMC_SegSetting();

	// operator
	MCMC_SegSetting& operator=(const MCMC_SegSetting a);

	// operators
	virtual void	SetLoadFileName(char *fname);

public:
	int		nheight,nwidth;
	int		nstep_from,nstep_to;
	double	dscale;
	bool	bsave_seg;
	bool	bcolor;
	bool	btexture;
	bool	bsame_size;
	int		nheight_seg,nwidth_seg;
	bool	bload_data;
	char	*pfile_name;

	bool visualize; // Siyuan
};

#define MAP_CREATE_CURVE_LAYER  true
#define MAP_NOTCREATE_CURVE_LAYER  false

////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
class MCMC_Map
{
public:
	// construction & destruction
	MCMC_Map();
	~MCMC_Map();

	// operations
	virtual	void		SetFilterResp(MCMC_FilterResp &resp)=0;
	inline MCMC_Layer_Regions* LayerRegion(void){return player_region;};
	inline	int			Height(void){if (player_region==NULL) return 0; else return player_region->height;};
	inline  int			Width(void){if (player_region==NULL) return 0; else return player_region->width;};

	virtual void		Synthesize(Raster_Color<uchar> &ras_syn_image, const char flag)=0;
	virtual void		Reconstruct(Raster_Color<uchar> &ras_syn_image)=0;
	inline	void		SetStep(const int istep){step=istep;};
	inline	int			Step(void){return step;};
	inline  double		GetT(void);									// get the tempture
	inline	double		GetTMedium(void){return GetT()/3.0;};


protected:
	inline	int			ValueInRange(const double a);
public:
	// region layer
	MCMC_Layer_Regions	*player_region;
	Raster<int>			ras_region_label;		// used for labeling regions

	MCMC_FilterResp		*prespFilter;
	mcmcMatrix<uchar>		mx_overlapping;			// the ids of curve and regions that are overlapping

protected:
	int					step;
};

inline	int	MCMC_Map::ValueInRange(const double a)
{
	int temp=(int)a;

	if (temp <= 0)				temp = 0;
	else if (temp >= 255)		temp = 255;

	return temp;
}

// get the tempture
inline double MCMC_Map::GetT(void)
{
	double drow,dcol,dstep;

	drow	= (double)Height();
	dcol	= (double)Width();
	dstep	= (double)step;

	if (prespFilter==NULL || !prespFilter->InColor())
//		return (0.05+3500.0/exp(dstep*115.0/(drow*dcol)));
		return (0.05+3500.0/exp(dstep*115.0/(drow*dcol/(300.0*200.0)*(240.0*170.0))));
	else
		return (0.05+7000.0/exp(dstep*115.0/(drow*dcol/(300.0*200.0)*(240.0*170.0))));
//		return (0.05+7000.0/exp(dstep*115.0/(drow*dcol)));
}


typedef MCMC_Model*  PMCMC_Model;

////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////
class MCMC_Map_2Layers :public MCMC_Map
{
public:
	// construction & destruction
	MCMC_Map_2Layers();
	~MCMC_Map_2Layers();

	// operators
	MCMC_Map_2Layers& operator=(MCMC_Map_2Layers &a);
	virtual void operator>>(ofstream &strm);
	virtual void operator<<(ifstream &strm);
	virtual void SaveToFile(char *file_name);
	virtual bool ReadFromFile(char *file_name);

	// operations
	virtual	void		SetFilterResp(MCMC_FilterResp &resp);

	inline	double		EnergyTotal(void);
	inline	double		EnergyLoglik(void);
	virtual void		Synthesize(Raster_Color<uchar> &ras_syn_image, const char flag);
	virtual void		Reconstruct(void);
	virtual void		Reconstruct(Raster_Color<uchar> &ras_syn_image);
	virtual	void		ComputeTotalEnergy(const bool brecompute_energyshape);
};

inline	double MCMC_Map_2Layers::EnergyTotal(void)
{
	double temp=0.0;

	if (player_region != NULL)
		temp += player_region->EnergyTotal();
	return temp;
};

inline	double	MCMC_Map_2Layers::EnergyLoglik(void)
{
	if (player_region == NULL)
		return 0.0;
	else
		return player_region->EnergyLoglik();
};


#endif
